package com.bc004346.travelus;

import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
import android.preference.MultiSelectListPreference;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceManager;
import android.view.MenuItem;

import com.bc004346.travelus.model.domain.TripMeOptions;
import com.bc004346.travelus.utility.Utility;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

import static com.bc004346.travelus.utility.Utility.log;

/**
 * A {@link PreferenceActivity} that presents a set of application settings. On
 * handset devices, settings are presented as a single list. On tablets,
 * settings are split by category, with category headers shown to the left of
 * the list of settings.
 * <p/>
 * See <a href="http://developer.android.com/design/patterns/settings.html">
 * Android Design: Settings</a> for design guidelines and the <a
 * href="http://developer.android.com/guide/topics/ui/settings.html">Settings
 * API Guide</a> for more information on developing a Settings UI.
 */
@SuppressWarnings("deprecation")
public class SettingsActivity extends PreferenceActivity {

    public static final String PREF_PNR_REFRESH_ENABLED = "pref_pnr_refresh_enabled";
    public static final String PREF_PNR_REFRESH_INTERVAL = "pref_pnr_refresh_interval";
    public static final String PREF_DAYS_TO_SEARCH = "pref_days_to_search";
    public static final String PREF_AVAILABILITY_REFRESH_ENABLED = "pref_availability_refresh_enabled";
    public static final String PREF_AVAILABILITY_REFRESH_INTERVAL = "pref_availability_refresh_interval";
    public static final String PREF_SEND_ERROR_REPORTS = "pref_send_error_reports";
    public static final String PREF_STANDBY_LIST = "pref_standby_list";
    public static final String PREF_TRIP_ME_ENABLED = "pref_trip_me";
    public static final String PREF_TRIP_ME_HOME_BASE = "pref_trip_me_home_base";
    public static final String PREF_TRIP_ME_FAVORITE_DESTINATIONS = "pref_trip_me_favorite_destinations";
    public static final String PREF_TRIP_ME_SEARCH_DAYS = "pref_trip_me_schedule";

    //<editor-fold desc="Properties">
    /**
     * A preference value change listener that updates the preference's summary
     * to reflect its new value.
     */
    private static Preference.OnPreferenceChangeListener sBindPreferenceSummaryToValueListener = new Preference.OnPreferenceChangeListener() {
        @Override
        public boolean onPreferenceChange(Preference preference, Object value) {
            String stringValue = value.toString();
            preference.setSummary(stringValue);
            return true;
        }
    };

    public static Boolean pnrRefreshEnabled(Context context) {
        return PreferenceManager
                .getDefaultSharedPreferences(context.getApplicationContext())
                .getBoolean(SettingsActivity.PREF_PNR_REFRESH_ENABLED, true);
    }

    //<editor-fold desc="Standby List helper">
    public static Set<String> standbyList(Context context) {
        return PreferenceManager
                .getDefaultSharedPreferences(context.getApplicationContext())
                .getStringSet(SettingsActivity.PREF_STANDBY_LIST, new HashSet<String>());
    }

    public static Set<String> getFavoriteDestinations(Context context) {
        Set<String> destinations = PreferenceManager
                .getDefaultSharedPreferences(context.getApplicationContext())
                .getStringSet(SettingsActivity.PREF_TRIP_ME_FAVORITE_DESTINATIONS, new HashSet<String>());
        for (String s : destinations) log("Favorite Destination: " + s);
        return destinations;
    }

    public static TripMeOptions getTripMeOptions(Context context) {
        TripMeOptions options = new TripMeOptions();
        options.setEnabled(PreferenceManager
                .getDefaultSharedPreferences(context.getApplicationContext())
                .getBoolean(SettingsActivity.PREF_TRIP_ME_ENABLED, false));
        options.setHomeBase(PreferenceManager
                .getDefaultSharedPreferences(context.getApplicationContext())
                .getString(SettingsActivity.PREF_TRIP_ME_HOME_BASE, "").toUpperCase());
        options.setFavoriteDestinations(getFavoriteDestinations(context));
        options.setSchedule(PreferenceManager
                .getDefaultSharedPreferences(context.getApplicationContext())
                .getStringSet(SettingsActivity.PREF_TRIP_ME_SEARCH_DAYS,
                        new HashSet<>(Arrays.asList("Sunday", "Tuesday", "Monday", "Thursday"))));
        return options;
    }

    public static void setHomeBase(Context context, String homeBase) {

        SharedPreferences settings = PreferenceManager
                .getDefaultSharedPreferences(context.getApplicationContext());
        SharedPreferences.Editor editor = settings.edit();
        editor.putString(SettingsActivity.PREF_TRIP_ME_HOME_BASE, homeBase);
        editor.putBoolean(SettingsActivity.PREF_TRIP_ME_ENABLED, true);
        editor.putStringSet(SettingsActivity.PREF_TRIP_ME_SEARCH_DAYS,
                new HashSet<>(Arrays.asList("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday")));
        editor.apply();
    }

    public static Set<String> addToStandbyList(Context context, String name) {
        Set<String> set = new HashSet<>();
        set.addAll(standbyList(context.getApplicationContext()));
        SharedPreferences settings = PreferenceManager
                .getDefaultSharedPreferences(context.getApplicationContext());
        SharedPreferences.Editor editor = settings.edit();
        set.add(name);
        editor.putStringSet(SettingsActivity.PREF_STANDBY_LIST, set);
        editor.apply();
        return set;
    }

    public static Set<String> setFavoriteDestinations(Context context, Set<String> set) {
        SharedPreferences settings = PreferenceManager
                .getDefaultSharedPreferences(context.getApplicationContext());
        SharedPreferences.Editor editor = settings.edit();
        editor.putStringSet(SettingsActivity.PREF_TRIP_ME_FAVORITE_DESTINATIONS, set);
        editor.apply();
        for (String s : set) log("Favorite Destination: " + s);
        return set;
    }

    public static Set<String> removeFromStandbyList(Context context, String name) {
        Set<String> set = new HashSet<>();
        set.addAll(standbyList(context.getApplicationContext()));
        SharedPreferences settings = PreferenceManager
                .getDefaultSharedPreferences(context.getApplicationContext());
        SharedPreferences.Editor editor = settings.edit();
        set.remove(name);
        editor.putStringSet(SettingsActivity.PREF_STANDBY_LIST, set);
        editor.apply();
        return set;
    }
    //</editor-fold>

    public static Boolean isOnStandbyList(Context context, String name) {
        return standbyList(context.getApplicationContext()).contains(name);
    }

    public static String pnrRefreshInterval(Context context) {
        SharedPreferences sp = PreferenceManager
                .getDefaultSharedPreferences(context.getApplicationContext());
        return sp.getString(SettingsActivity.PREF_PNR_REFRESH_INTERVAL, "3");
    }

    public static Boolean availabilityRefreshEnabled(Context context) {
        return PreferenceManager
                .getDefaultSharedPreferences(context.getApplicationContext())
                .getBoolean(SettingsActivity.PREF_AVAILABILITY_REFRESH_ENABLED, true);
    }

    public static String availabilityRefreshInterval(Context context) {
        return PreferenceManager
                .getDefaultSharedPreferences(context.getApplicationContext())
                .getString(SettingsActivity.PREF_AVAILABILITY_REFRESH_INTERVAL, "3");
    }

    public static String daysToSearch(Context context) {
        return PreferenceManager
                .getDefaultSharedPreferences(context.getApplicationContext())
                .getString(SettingsActivity.PREF_DAYS_TO_SEARCH, "30");
    }

    public static Boolean sendErrorReportsEnabled(Context context) {
        return PreferenceManager
                .getDefaultSharedPreferences(context.getApplicationContext())
                .getBoolean(SettingsActivity.PREF_SEND_ERROR_REPORTS, true);
    }

    //</editor-fold>

    public static void setSendErrorReportsEnabled(Context context) {
        SharedPreferences settings = PreferenceManager
                .getDefaultSharedPreferences(context.getApplicationContext());
        SharedPreferences.Editor editor = settings.edit();
        editor.putBoolean(SettingsActivity.PREF_SEND_ERROR_REPORTS, false);
        editor.apply();
    }

    /**
     * Binds a preference's summary to its value. More specifically, when the
     * preference's value is changed, its summary (line of text below the
     * preference title) is updated to reflect the value. The summary is also
     * immediately updated upon calling this method. The exact display format is
     * dependent on the type of preference.
     *
     * @see #sBindPreferenceSummaryToValueListener
     */
    private void bindPreferenceSummaryToValue(Preference preference) {
        // Set the listener to watch for value changes.
        preference.setOnPreferenceChangeListener(sBindPreferenceSummaryToValueListener);

        // Trigger the listener immediately with the preference's
        // current value.
        if (preference.getKey().equals(PREF_TRIP_ME_FAVORITE_DESTINATIONS)
                || preference.getKey().equals(PREF_STANDBY_LIST)) {
            Set<String> hs = PreferenceManager
                    .getDefaultSharedPreferences(getApplicationContext())
                    .getStringSet(preference.getKey(), new HashSet<String>());
            sBindPreferenceSummaryToValueListener.onPreferenceChange(preference, hs);
            MultiSelectListPreference p = (MultiSelectListPreference) preference;
            p.setValues(hs);
            p.setEntries(hs.toArray(new CharSequence[hs.size()]));
            p.setEntryValues(hs.toArray(new CharSequence[hs.size()]));
        } else
        if (preference.getClass() == MultiSelectListPreference.class) {
            Set<String> hs = PreferenceManager
                    .getDefaultSharedPreferences(getApplicationContext())
                    .getStringSet(preference.getKey(), new HashSet<String>());
            sBindPreferenceSummaryToValueListener.onPreferenceChange(preference, hs);

        } else if (preference.getClass() == CheckBoxPreference.class) {
            sBindPreferenceSummaryToValueListener.onPreferenceChange(preference,
                    PreferenceManager
                            .getDefaultSharedPreferences(getApplicationContext())
                            .getBoolean(preference.getKey(), false)
            );
        } else {
            sBindPreferenceSummaryToValueListener.onPreferenceChange(preference,
                    PreferenceManager
                            .getDefaultSharedPreferences(getApplicationContext())
                            .getString(preference.getKey(), "")
            );
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                finish();
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        try {
            if (getActionBar() != null)
                getActionBar().setDisplayHomeAsUpEnabled(true);
            Utility.onStart(this);
            setupSimplePreferencesScreen();
        } catch (Exception e) {
            log(e, this);
        }
    }

    /**
     * Shows the simplified settings UI if the device configuration if the
     * device configuration dictates that a simplified, single-pane UI should be
     * shown.
     */
    private void setupSimplePreferencesScreen() {

        // Add 'general' preferences.
        addPreferencesFromResource(R.xml.pref_general);

        // Bind the summaries of EditText/List/Dialog/Ringtone preferences to
        // their values. When their values change, their summaries are updated
        // to reflect the new value, per the Android Design guidelines.
        bindPreferenceSummaryToValue(findPreference(PREF_PNR_REFRESH_ENABLED));
        bindPreferenceSummaryToValue(findPreference(PREF_PNR_REFRESH_INTERVAL));
        bindPreferenceSummaryToValue(findPreference(PREF_AVAILABILITY_REFRESH_ENABLED));
        bindPreferenceSummaryToValue(findPreference(PREF_AVAILABILITY_REFRESH_INTERVAL));
        bindPreferenceSummaryToValue(findPreference(PREF_DAYS_TO_SEARCH));
        bindPreferenceSummaryToValue(findPreference(PREF_SEND_ERROR_REPORTS));
        bindPreferenceSummaryToValue(findPreference(PREF_STANDBY_LIST));
        bindPreferenceSummaryToValue(findPreference(PREF_TRIP_ME_ENABLED));
        bindPreferenceSummaryToValue(findPreference(PREF_TRIP_ME_HOME_BASE));
        bindPreferenceSummaryToValue(findPreference(PREF_TRIP_ME_FAVORITE_DESTINATIONS));
        bindPreferenceSummaryToValue(findPreference(PREF_TRIP_ME_SEARCH_DAYS));
    }
}
